import React, { useState, useEffect } from 'react';
import { 
  PlusIcon, 
  PencilIcon, 
  TrashIcon, 
  XMarkIcon
} from '@heroicons/react/24/outline';
import { apiService } from '../services/api';
import PageHeader from './PageHeader';
import { 
  // FormInput, 
  RadioGroup, 
  // Button, 
  // Modal,
  CuboxButton, 
  CuboxInput, 
  CuboxModal 
} from './ui';

const Nodes = () => {
  const [nodes, setNodes] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [showModal, setShowModal] = useState(false);
  const [editingNode, setEditingNode] = useState(null);

  const [formData, setFormData] = useState({
    name: '',
    address: '',
    ssh_port: 22,
    ssh_user: '',
    ssh_key_path: '',
    ssh_password: '',
    remote_dir: '/opt/trode'
  });

  const [validationErrors, setValidationErrors] = useState({});
  const [sshAuthMethod, setSshAuthMethod] = useState('password'); // 'password' or 'key'
  const [validationStatus, setValidationStatus] = useState(null);
  const [isValidating, setIsValidating] = useState(false);

  const [pendingSubmit, setPendingSubmit] = useState(false);

  // SSH authentication options
  const sshAuthOptions = [
    { value: 'password', label: 'Password' },
    { value: 'key', label: 'SSH Key' }
  ];

  // Validation functions
  const validateUsername = (username) => {
    if (!username) return 'Username is required';
    if (username.length < 2) return 'Username must be at least 2 characters';
    if (username.length > 32) return 'Username must be less than 32 characters';
    if (!/^[a-zA-Z0-9_-]+$/.test(username)) return 'Username can only contain letters, numbers, underscores, and hyphens';
    return null;
  };

  const validateIpAddress = (address) => {
    if (!address) return 'IP address is required';
    
    // Check for valid IP address format
    const ipRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
    // Check for valid hostname format
    const hostnameRegex = /^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
    
    if (!ipRegex.test(address) && !hostnameRegex.test(address)) {
      return 'Please enter a valid IP address or hostname';
    }
    return null;
  };

  const validateForm = () => {
    const errors = {};
    
    const usernameError = validateUsername(formData.ssh_user);
    if (usernameError) errors.ssh_user = usernameError;
    
    const addressError = validateIpAddress(formData.address);
    if (addressError) errors.address = addressError;
    
    if (!formData.name.trim()) errors.name = 'Name is required';
    
    if (sshAuthMethod === 'password' && !formData.ssh_password) {
      errors.ssh_password = 'SSH password is required when using password authentication';
    }
    
    if (sshAuthMethod === 'key' && !formData.ssh_key_path) {
      errors.ssh_key_path = 'SSH key path is required when using key authentication';
    }
    
    setValidationErrors(errors);
    return Object.keys(errors).length === 0;
  };

  // Fetch nodes from API
  const fetchNodes = async () => {
    try {
      setLoading(true);
      const data = await apiService.getNodes();
      setNodes(data.nodes || []);
      setError(null);
    } catch (err) {
      setError(`Failed to fetch nodes: ${err.message}`);
      console.error('Error fetching nodes:', err);
    } finally {
      setLoading(false);
    }
  };

  // Load nodes on component mount
  useEffect(() => {
    fetchNodes();
  }, []);

  // Reset form data
  const resetForm = () => {
    setFormData({
      name: '',
      address: '',
      ssh_port: 22,
      ssh_user: '',
      ssh_key_path: '',
      ssh_password: '',
      remote_dir: '/opt/trode'
    });
    setEditingNode(null);
    setValidationErrors({});
    setSshAuthMethod('password');
    setValidationStatus(null);
  };

  // Open modal for creating/editing node
  const openModal = (node = null) => {
    if (node) {
      setFormData({
        name: node.name,
        address: node.address,
        ssh_port: node.ssh_port,
        ssh_user: node.ssh_user,
        ssh_key_path: node.ssh_key_path || '',
        ssh_password: node.ssh_password || '',
        remote_dir: node.remote_dir
      });
      // Determine SSH auth method based on existing data
      setSshAuthMethod(node.ssh_key_path ? 'key' : 'password');
      setEditingNode(node);
    } else {
      resetForm();
    }
    setShowModal(true);
  };

  // Close modal
  const closeModal = () => {
    setShowModal(false);
    resetForm();
  };

  // Handle form input changes
  const handleInputChange = (e) => {
    const { name, value } = e.target;
    setFormData(prev => ({
      ...prev,
      [name]: value
    }));
    
    // Clear validation error for this field
    if (validationErrors[name]) {
      setValidationErrors(prev => ({
        ...prev,
        [name]: null
      }));
    }
  };

  // Handle SSH auth method change
  const handleAuthMethodChange = (method) => {
    setSshAuthMethod(method);
    // Clear validation errors for both auth fields
    setValidationErrors(prev => ({
      ...prev,
      ssh_password: null,
      ssh_key_path: null
    }));
    // Clear validation status when auth method changes
    setValidationStatus(null);
  };

  // Handle blur on password/key fields
  const handleAuthFieldBlur = async (e) => {
    // Only validate if the relevant field is filled and required fields are present
    if (
      (sshAuthMethod === 'password' && formData.ssh_password && formData.address && formData.ssh_user) ||
      (sshAuthMethod === 'key' && formData.ssh_key_path && formData.address && formData.ssh_user)
    ) {
      await validateSSHCredentials();
    }
  };

  // Validate SSH credentials
  const validateSSHCredentials = async () => {
    if (!formData.address || !formData.ssh_user) {
      setError('Address and SSH user are required for validation');
      return;
    }

    if (sshAuthMethod === 'password' && !formData.ssh_password) {
      setError('SSH password is required for validation');
      return;
    }

    if (sshAuthMethod === 'key' && !formData.ssh_key_path) {
      setError('SSH key path is required for validation');
      return;
    }

    setIsValidating(true);
    setValidationStatus(null);
    setError(null);

    try {
      const data = await apiService.validateNode(formData);
      if (data.success) {
        setValidationStatus(data.validation);
        if (data.validation.valid) {
          setError(null);
        } else {
          setError(`SSH validation failed: ${data.validation.error}`);
        }
      }
    } catch (err) {
      setError(`Validation failed: ${err.message}`);
      console.error('Error validating SSH credentials:', err);
    } finally {
      setIsValidating(false);
    }
  };

  // Handle form submission
  const handleSubmit = async (e) => {
    e.preventDefault();
    submitNode();
  };

  // Modified submitNode to wait for validation if needed
  const submitNode = async () => {
    if (isValidating) return; // Prevent double submit
    setPendingSubmit(true);
    // If validation hasn't run or is invalid, run it first
    if (!validationStatus || !validationStatus.valid) {
      await validateSSHCredentials();
      setPendingSubmit(false);
      return;
    }
    setPendingSubmit(false);
    if (!validateForm()) {
      console.log("VALIDATION ERRORS", validationErrors);
      return;
    }
    try {
      let data;
      if (editingNode) {
        data = await apiService.updateNode(editingNode.id, formData);
      } else {
        data = await apiService.createNode(formData);
      }
      if (data.success) {
        closeModal();
        fetchNodes(); // Refresh the list
      }
    } catch (err) {
      setError(`Failed to ${editingNode ? 'update' : 'create'} node: ${err.message}`);
      console.error('Error saving node:', err);
    }
  };

  // Delete node
  const deleteNode = async (nodeId) => {
    if (!window.confirm('Are you sure you want to delete this node?')) {
      return;
    }

    try {
      const data = await apiService.deleteNode(nodeId);
      if (data.success) {
        fetchNodes(); // Refresh the list
      }
    } catch (err) {
      setError(`Failed to delete node: ${err.message}`);
      console.error('Error deleting node:', err);
    }
  };

  if (loading) {
    return (
      <div className="flex items-center justify-center min-h-screen">
        <div className="animate-spin rounded-full h-32 w-32 border-b-2 border-primary-600"></div>
      </div>
    );
  }

  return (
    <div className="min-h-screen bg-gray-50">
      <PageHeader>
        <CuboxButton 
          onClick={() => openModal()}
          cornerRadius={12}
          size="md"
          width={140}
        >
          <PlusIcon className="h-5 w-5 mr-2" />
          Add Node
        </CuboxButton>
      </PageHeader>

      {/* Error Alert */}
      {error && (
        <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 mt-6">
          <div className="bg-red-50 border border-red-200 rounded-md p-4">
            <div className="flex">
              <div className="flex-shrink-0">
                <XMarkIcon className="h-5 w-5 text-red-400" />
              </div>
              <div className="ml-3">
                <h3 className="text-sm font-medium text-red-800">Error</h3>
                <div className="mt-2 text-sm text-red-700">{error}</div>
              </div>
              <div className="ml-auto pl-3">
                <button
                  onClick={() => setError(null)}
                  className="inline-flex bg-red-50 rounded-md p-1.5 text-red-500 hover:bg-red-100"
                >
                  <XMarkIcon className="h-5 w-5" />
                </button>
              </div>
            </div>
          </div>
        </div>
      )}

      {/* Nodes Table */}
      <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 mt-6">
        <div className="bg-white shadow overflow-hidden sm:rounded-md">
          {nodes.length === 0 ? (
            <div className="text-center py-12">
              <svg
                className="mx-auto h-12 w-12 text-gray-400"
                fill="none"
                viewBox="0 0 24 24"
                stroke="currentColor"
              >
                <path
                  strokeLinecap="round"
                  strokeLinejoin="round"
                  strokeWidth={2}
                  d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"
                />
              </svg>
              <h3 className="mt-2 text-sm font-medium text-gray-900">No nodes</h3>
              <p className="mt-1 text-sm text-gray-500">
                Get started by creating a new node.
              </p>
              <div className="mt-6">
                <CuboxButton 
                  onClick={() => openModal()}
                  cornerRadius={12}
                  size="md"
                  width={140}
                >
                  <PlusIcon className="h-5 w-5 mr-2" />
                  Add Node
                </CuboxButton>
              </div>
            </div>
          ) : (
            <ul className="divide-y divide-gray-200">
              {nodes.map((node) => (
                <li key={node.id} className="px-6 py-4">
                  <div className="flex items-center justify-between">
                    <div className="flex items-center">
                      <div className="flex-shrink-0">
                        <div className="h-10 w-10 rounded-full bg-primary-100 flex items-center justify-center">
                          <svg className="h-6 w-6 text-primary-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 12h14M5 12a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v4a2 2 0 01-2 2M5 12a2 2 0 00-2 2v4a2 2 0 002 2h14a2 2 0 002-2v-4a2 2 0 00-2-2m-2-4h.01M17 16h.01" />
                          </svg>
                        </div>
                      </div>
                      <div className="ml-4">
                        <div className="flex items-center">
                          <p className="text-sm font-medium text-gray-900">{node.name}</p>
                          <span className="ml-2 inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
                            Active
                          </span>
                        </div>
                        <div className="mt-1 flex items-center text-sm text-gray-500">
                          <span>{node.address}:{node.ssh_port}</span>
                          <span className="mx-2">•</span>
                          <span>{node.ssh_user}</span>
                        </div>
                        <div className="mt-1 text-xs text-gray-400">
                          Created: {new Date(node.created_at).toLocaleDateString()}
                          {node.updated_at !== node.created_at && (
                            <span className="ml-4">
                              Updated: {new Date(node.updated_at).toLocaleDateString()}
                            </span>
                          )}
                        </div>
                      </div>
                    </div>
                    <div className="flex items-center space-x-2">
                      <CuboxButton
                        variant="secondary"
                        size="sm"
                        cornerRadius={8}
                        onClick={() => openModal(node)}
                        width={140}
                      >
                        <PencilIcon className="h-4 w-4" />
                      </CuboxButton>
                      <CuboxButton
                        variant="danger"
                        size="sm"
                        cornerRadius={8}
                        onClick={() => deleteNode(node.id)}
                        width={140}
                      >
                        <TrashIcon className="h-4 w-4" />
                      </CuboxButton>
                    </div>
                  </div>
                </li>
              ))}
            </ul>
          )}
        </div>
      </div>

      {/* Cubox Modal */}
      <CuboxModal
        isOpen={showModal}
        onClose={closeModal}
        title={editingNode ? 'Edit Node' : 'Add New Node'}
        size="md"
        cornerRadius={16}
        strokeWidth={1}
        isOutlined={true}
      >
        <form onSubmit={handleSubmit} className="space-y-4">
          <CuboxInput
            label="Name"
            name="name"
            value={formData.name}
            onChange={handleInputChange}
            required
            error={validationErrors.name}
            cornerRadius={8}
          />
          
          <CuboxInput
            label="Address"
            name="address"
            value={formData.address}
            onChange={handleInputChange}
            required
            placeholder="192.168.1.100 or hostname.com"
            error={validationErrors.address}
            cornerRadius={8}
          />

          <div className="grid grid-cols-2 gap-4">
            <CuboxInput
              label="SSH Port"
              name="ssh_port"
              type="number"
              value={formData.ssh_port}
              onChange={handleInputChange}
              cornerRadius={8}
            />
            <CuboxInput
              label="SSH User"
              name="ssh_user"
              value={formData.ssh_user}
              onChange={handleInputChange}
              required
              error={validationErrors.ssh_user}
              cornerRadius={8}
            />
          </div>

          <RadioGroup
            label="SSH Authentication"
            name="ssh_auth_method"
            value={sshAuthMethod}
            onChange={handleAuthMethodChange}
            options={sshAuthOptions}
          />

          {sshAuthMethod === 'key' && (
            <CuboxInput
              label="SSH Key Path"
              name="ssh_key_path"
              value={formData.ssh_key_path}
              onChange={handleInputChange}
              onBlur={handleAuthFieldBlur}
              placeholder="/path/to/private/key"
              required
              error={validationErrors.ssh_key_path}
              cornerRadius={8}
            />
          )}

          {sshAuthMethod === 'password' && (
            <CuboxInput
              label="SSH Password"
              name="ssh_password"
              type="password"
              value={formData.ssh_password}
              onChange={handleInputChange}
              onBlur={handleAuthFieldBlur}
              required
              error={validationErrors.ssh_password}
              cornerRadius={8}
            />
          )}

          <CuboxInput
            label="Remote Directory"
            name="remote_dir"
            value={formData.remote_dir}
            onChange={handleInputChange}
            cornerRadius={8}
          />

          {/* SSH Validation Section */}
          <div className="space-y-3">
            {/* Validation Status Display */}
            {validationStatus && (
              <div className={`p-3 rounded-md border ${
                validationStatus.valid 
                  ? 'bg-green-50 border-green-200 text-green-800' 
                  : 'bg-red-50 border-red-200 text-red-800'
              }`}>
                <div className="flex items-center">
                  <div className="flex-shrink-0">
                    {validationStatus.valid ? (
                      <svg className="h-5 w-5 text-green-400" fill="currentColor" viewBox="0 0 20 20">
                        <path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" />
                      </svg>
                    ) : (
                      <svg className="h-5 w-5 text-red-400" fill="currentColor" viewBox="0 0 20 20">
                        <path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clipRule="evenodd" />
                      </svg>
                    )}
                  </div>
                  <div className="ml-3">
                    <p className="text-sm font-medium">
                      {validationStatus.valid ? 'Connection Successful' : 'Connection Failed'}
                    </p>
                    <p className="text-sm mt-1">{validationStatus.message}</p>
                    {validationStatus.hasSudo && (
                      <p className="text-sm mt-1 text-green-600">
                        ✓ Sudo access confirmed
                      </p>
                    )}
                  </div>
                </div>
              </div>
            )}
          </div>

          <div className="flex justify-end space-x-3 pt-4">
            <CuboxButton 
              variant="secondary" 
              onClick={closeModal}
              cornerRadius={8}
              width={140}
              disabled={isValidating}
            >
              Cancel
            </CuboxButton>
            <CuboxButton 
              onClick={submitNode}
              cornerRadius={8}
              width={140}
              disabled={isValidating || (validationStatus && !validationStatus.valid)}
              style={isValidating ? { opacity: 0.5, pointerEvents: 'none' } : {}}
            >
              {isValidating ? (editingNode ? 'Validating...' : 'Validating...') : (editingNode ? 'Update' : 'Create')}
            </CuboxButton>
          </div>
        </form>
      </CuboxModal>
    </div>
  );
};

export default Nodes;